package ex1;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.Random;

public class Ex1 {
	static Random randomizer = new Random();
	
	public static void main(String[] argv){

		for (int i = 0; ; ++ i){
			
			int xSize=randomizer.nextInt(20) + 1;
			int ySize=randomizer.nextInt(20) + 1;
			int hSplit=randomizer.nextInt(xSize) + 1;
			int vSplit=randomizer.nextInt(ySize) + 1;
			int nGenerations=randomizer.nextInt(15);
						
			boolean[][] field=createRandomField(xSize, ySize);
			
			System.out.println("Run Number: " + i);
			System.out.println("Size: " + xSize + "x" + ySize + " Split: " + hSplit + ":" + vSplit);
			System.out.println("Generations: " + nGenerations);
//			System.out.println("Initial Field: ");
//			printArray(field);
			
			if (vSplit>field.length||hSplit>field[0].length){
				System.err.println("Wrong number of splits specified");
				System.exit(-1);
			}
			
			GameOfLife sGol=new SerialGameOfLife();
			GameOfLife pGol=new ParallelGameOfLife();
			
			boolean[][] resultSerial=sGol.invoke(field,hSplit,vSplit, nGenerations);	
			boolean[][] resultParallel=pGol.invoke(field,hSplit,vSplit, nGenerations);
			
//			System.out.println("Result Field: ");
//			printArray(resultSerial);
//			System.out.println("==========================");
//			System.out.println("==========================");
//			System.out.println("==========================");
//			System.out.println("==========================");
			System.out.println("==========================");

					
			if (compareArrays(resultParallel,resultSerial)){
				System.out.println("Success!");
			}else{
				System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
				System.out.println("Parallel version results do not match!!");
				System.exit(-1);
			}
		}
	}
	

	//This funcion prints the output in a standard way to allow
	//coherent output comparison.
	//The arr parameter should contain a matrix of zero and ones.
	// This in no way should be considered a hint re/ 
	// internal data structure.
	
	public static void printArray(boolean [][] arr){
		for(boolean [] row: arr){
			for (boolean cell: row){
				System.out.print((cell?'#':'-'));
			}
			System.out.println();
		}
	}

	public static void printArray(boolean [][] arr, String filename) throws Exception{
		BufferedWriter output= new BufferedWriter(new FileWriter(filename));
		
		for(boolean [] row: arr){
			for (boolean cell: row){
				output.write((cell?'1':'0'));
			}
			output.newLine();
		}
		output.close();
	}
	public static boolean compareArrays(boolean [][]arr1,boolean [][]arr2){
		if (arr1==null || arr2==null) {
			return false;
		}
		if (arr1.length!=arr2.length) {
			return false;
		}
		for (int i=0;i<arr1.length;i++){
			if (arr1[i].length!=arr2[i].length) {
				return false;
			}
			for (int j=0;j<arr1[i].length;j++){
				if (arr1[i][j]!=arr2[i][j]){
					return false;
				}
			}
		}
		return true;
	}

	public static boolean[][] createRandomField(int xSize, int ySize){
		boolean[][] field = new boolean[ySize][xSize];
		for (int y = 0; y < ySize; ++y){
			for(int x = 0; x < xSize; ++x){
				field[y][x] = randomizer.nextBoolean();
			}
		}
		return field;
	}
}
